import frappe
from frappe import _
from frappe.utils import flt

def on_submit(doc, method):
    """采购发票提交后,更新工单对应工序明细的已结算数量和Wip Transfer Item的状态"""
    update_work_order_operation_invoiced_qty(doc)
    update_wip_transfer_item_status(doc)

def on_cancel(doc, method):
    """采购发票取消时,回滚工单对应工序明细的已结算数量和Wip Transfer Item的状态"""
    update_work_order_operation_invoiced_qty(doc, cancel=True)
    update_wip_transfer_item_status(doc, cancel=True)

def update_work_order_operation_invoiced_qty(doc, cancel=False):
    """更新工单工序明细的已结算数量"""
    # 遍历采购发票的物料明细
    for item in doc.items:
        # 检查是否有关联的加工单
        if item.custom_job_card:
            # 获取加工单文档
            job_card = frappe.get_doc("Job Card", item.custom_job_card)
            
            # 检查加工单是否有工单和工序明细ID
            if job_card.work_order and job_card.operation_id:
                # 获取工单文档
                work_order = frappe.get_doc("Work Order", job_card.work_order)
                
                # 查找匹配的工序明细（通过operation_id直接定位）
                operation_found = False
                for operation in work_order.operations:
                    if operation.name == job_card.operation_id:
                        operation_found = True
                        
                        # 计算要更新的数量
                        qty_to_update = item.qty
                        if cancel:
                            # 如果是取消发票，则减少已结算数量
                            new_invoiced_qty = flt(operation.custom_invoiced_qty) - flt(qty_to_update)
                        else:
                            # 如果是提交发票，则增加已结算数量
                            new_invoiced_qty = flt(operation.custom_invoiced_qty) + flt(qty_to_update)
                        
                        # 更新已结算数量
                        operation.custom_invoiced_qty = new_invoiced_qty
                        
                        break
                
                # 如果找到匹配的工序明细，保存工单
                if operation_found:
                    work_order.flags.ignore_validate_update_after_submit = True
                    work_order.save(ignore_permissions=True)
                    # 不要在这里调用 frappe.db.commit()，让Frappe框架来管理事务

def update_wip_transfer_item_status(doc, cancel=False):
    """更新Wip Transfer Item的状态"""
    # 收集需要更新的Wip Transfer Item
    wip_items_to_update = {}
    
    # 遍历采购发票的物料明细
    for item in doc.items:
        if item.custom_wip_transfer and item.custom_wip_transfer_item:
            if item.custom_wip_transfer_item not in wip_items_to_update:
                wip_items_to_update[item.custom_wip_transfer_item] = {
                    'qty': 0,
                    'wip_transfer': item.custom_wip_transfer
                }
            
            # 累加或减少数量
            if cancel:
                wip_items_to_update[item.custom_wip_transfer_item]['qty'] -= flt(item.qty)
            else:
                wip_items_to_update[item.custom_wip_transfer_item]['qty'] += flt(item.qty)
    
    # 更新每个Wip Transfer Item的状态
    for wip_item_name, data in wip_items_to_update.items():
        # 获取Wip Transfer Item
        wip_item = frappe.get_doc("Wip Transfer Item", wip_item_name)
        
        # 计算新的已开票数量
        current_invoiced_qty = flt(wip_item.invoiced_qty) or 0
        qty_change = data['qty']
        new_invoiced_qty = current_invoiced_qty + qty_change
        
        
        # 检查已开票数量是否大于良品数量，如果是则抛出异常
        if new_invoiced_qty > wip_item.qty:
            frappe.throw(_("Invoiced quantity cannot exceed quality quantity for Wip Transfer Item {0}. Invoiced: {1}, Quality: {2}")
                        .format(wip_item_name, new_invoiced_qty, wip_item.qty))
        
        # 确定状态
        if new_invoiced_qty == wip_item.qty:  # 修改为精确匹配，而不是大于等于
            status = "Invoiced"
        elif new_invoiced_qty > 0:
            status = "Partially Invoiced"
        else:
            status = "Not Invoiced"
        
        # 更新状态和已开票数量
        frappe.db.set_value("Wip Transfer Item", wip_item_name, {
            "status": status,
            "invoiced_qty": new_invoiced_qty
        })